#include <48func.h>
typedef struct node_s {
    int num;
    struct node_s * pNext;
} node_t;
typedef struct queue_s {
    node_t * pFront;
    node_t * pRear;
    int size;
} queue_t;
typedef struct shareRes_s { 
    queue_t queue;
    pthread_mutex_t mutex;
    pthread_cond_t cond;
}shareRes_t;
void Enqueue(queue_t *pqueue, int num){
    node_t * pNew = (node_t *)calloc(1,sizeof(node_t));
    pNew->num = num;
    if(pqueue->size == 0){
        pqueue->pFront = pNew;
        pqueue->pRear = pNew;
    }
    else{
        pqueue->pRear->pNext = pNew;
        pqueue->pRear = pNew;
    }
    ++pqueue->size;
}
void Dequeue(queue_t *pqueue){
    // 假设队列中有至少一个结点
    node_t * pCur = pqueue->pFront;
    pqueue->pFront = pCur->pNext;
    --pqueue->size;
    free(pCur);
}
void visitqueue(queue_t *pqueue){
    node_t * pCur = pqueue->pFront;
    while(pCur){
        printf("%3d ", pCur->num);
        pCur = pCur->pNext;
    }
    printf("\n");
}
void *producer(void *arg){
    shareRes_t * pshareRes = (shareRes_t *)arg;
    while(1){
        pthread_mutex_lock(&pshareRes->mutex);
        while(pshareRes->queue.size >= 10){
            pthread_cond_wait(&pshareRes->cond,&pshareRes->mutex);
        }
        int num = rand()%1000;
        Enqueue(&pshareRes->queue,num);
        printf("producer, size = %d, num = %d, queue =  ",pshareRes->queue.size, num);
        visitqueue(&pshareRes->queue);
        pthread_cond_broadcast(&pshareRes->cond);
        pthread_mutex_unlock(&pshareRes->mutex);
        sleep(3);
    }
}
void *consumer(void *arg){
    shareRes_t * pshareRes = (shareRes_t *)arg;
    sleep(5);
    while(1){
        pthread_mutex_lock(&pshareRes->mutex);
        while(pshareRes->queue.size <= 0){
            pthread_cond_wait(&pshareRes->cond,&pshareRes->mutex);
        }
        int front = pshareRes->queue.pFront->num;
        Dequeue(&pshareRes->queue);
        printf("consumer ,size = %d,  front = %d, queue =  ",pshareRes->queue.size, front);
        visitqueue(&pshareRes->queue);
        pthread_cond_broadcast(&pshareRes->cond);
        pthread_mutex_unlock(&pshareRes->mutex);
        sleep(1);
    }
}
int main()
{
    // 初始化共享资源
    shareRes_t shareRes;
    pthread_cond_init(&shareRes.cond,NULL);
    pthread_mutex_init(&shareRes.mutex,NULL);
    memset(&shareRes.queue,0,sizeof(queue_t));
    for(int i = 0; i < 8; ++i){
        int num = rand()%1000;
        Enqueue(&shareRes.queue,num);
        printf("num = %d\n", num);
    }
    visitqueue(&shareRes.queue);
    pthread_t tid1,tid2,tid3,tid4,tid5;
    pthread_create(&tid1,NULL,producer,&shareRes);
    pthread_create(&tid2,NULL,producer,&shareRes);
    pthread_create(&tid3,NULL,producer,&shareRes);
    pthread_create(&tid4,NULL,consumer,&shareRes);
    pthread_create(&tid5,NULL,consumer,&shareRes);
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);
    pthread_join(tid4,NULL);
    pthread_join(tid5,NULL);
    return 0;
}

